﻿// ----------------------------------------------------------------------------------------
// Author:                    Magaly Vargas y Joaquín López
// Company:                   ALBALIA INTERACTIVA S.L.
// Assembly version:          1.0.0.0
// Date:                      22/02/2010
// Time:                      12:00
// Solution Name:             OffInvoiceWordAddIn
// Solution Filename:         OffInvoiceWordAddIn
// Solution FullFilename:     C:\Desarrollo\OffInvoiceWordAddIn
// Project Name:              OffInvoiceWordAddIn
// Project Filename:          OffInvoiceWordAddIn.csproj
// Project FullFilename:      C:\Desarrollo\OffInvoiceWordAddIn\OffInvoiceWordAddIn.csproj
// Project Item Name:         ValidateController.cs
// Project Item Filename:     ValidateController.cs
// Project Item FullFilename: C:\Desarrollo\OffInvoiceWordAddIn\ValidateController.cs
// Project Item Kind:         Código
// Purpose:                   
//Copyright © 2009 - 2010 Albalia Interactiva S.L. Reservados todos los derechos.
// ----------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OffInvoiceWordAddIn.FacturaeFiles;
using System.Xml.Serialization;
using Office = Microsoft.Office.Core;
using System.IO;
using System.Xml;
using System.Globalization;
using System.Windows.Forms;
using Xades;
using OffInvoiceWordAddIn.UBLFiles;
using OffInvoiceWordAddIn.CIIFiles;
using Microsoft.Office.Interop.Word;

namespace OffInvoiceWordAddIn
{
    /// <summary>
    /// Método que controla las validaciones de las facturas
    /// </summary>
    class ValidateController
    {

        #region "Fields"

        /// <summary>
        /// Campo que almacena el resultado de la validación
        /// </summary>
        public bool result { get; set; }

        /// <summary>
        /// Campo con la cultura para los numeros, fechas y monedas
        /// </summary>
        CultureInfo cInfo = null;

        /// <summary>
        /// Campo con el formato para los numeros
        /// </summary>
        FieldFormats ff = null;

        /// <summary>
        /// Campo con los calculos de la factura
        /// </summary>
        Calculos calculos = null;


        #endregion

        #region "Constructors"

        /// <summary>
        /// Constructor por defecto
        /// </summary>
        public ValidateController()
        {
            cInfo = new CultureInfo(Globals.ThisAddIn.Application.LanguageSettings.get_LanguageID(Microsoft.Office.Core.MsoAppLanguageID.msoLanguageIDUI));
            ff = new FieldFormats(cInfo, cInfo.NumberFormat, cInfo.Name);
            calculos = new Calculos(ff);
        }


        /// <summary>
        /// Contructor con parámetros
        /// </summary>
        /// <param name="customPartID">Identificador de la factura dentro del xlsx</param>
        /// <param name="agregarRecibidas">Parámetro que indica si la factura se desea agregar a recibidas o no</param>
        public ValidateController(string customPartID, bool agregarRecibidas)
        {
            cInfo = new CultureInfo(Globals.ThisAddIn.Application.LanguageSettings.get_LanguageID(Microsoft.Office.Core.MsoAppLanguageID.msoLanguageIDUI));
            ff = new FieldFormats(cInfo, cInfo.NumberFormat, cInfo.Name);
            calculos = new Calculos(ff);

            Office.CustomXMLPart customPartReceived;

            if (customPartID == null)
            {
                ControlMessages controlM = ControlMessages.getInstance();
                throw new Exception(controlM.getMessage(ControlMessages.Msg.ErrorNoCustomPartFound));
            }
            else
            {
                customPartReceived = Globals.ThisAddIn.Application.ActiveDocument.CustomXMLParts.SelectByID(customPartID);

                if (customPartReceived == null)
                {
                    validatePaper(InvoceTypes.FACTURAE_3_1, agregarRecibidas);
                }
                else
                {
                    XmlDocument doc = new XmlDocument();
                    doc.PreserveWhitespace = true;
                    doc.LoadXml(customPartReceived.DocumentElement.XML);
                    if (doc.DocumentElement.NamespaceURI.Equals("urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"))
                    {
                        result = validateUBL(doc, agregarRecibidas);
                    }
                    else if (doc.DocumentElement.NamespaceURI.Equals("urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:1"))
                    {
                        result = validateCII(doc, agregarRecibidas);
                    }
                    else
                    {
                        result = validateFacturae(doc, agregarRecibidas);
                    }
                }
            }
        }

        #endregion

        #region "Public Methods"

        /// <summary>
        /// Método que valida una factura en parel
        /// </summary>
        /// <param name="formatoFactura">Formato de la factura</param>
        /// <param name="agregarRecibidas">Parámetro que indica si la factura se desea agregar a recibidas o no</param>
        /// <returns>Resultado de la validación</returns>
        public bool validatePaper(int formatoFactura, bool agregarRecibidas)
        {
            string temporalExportPath = Path.GetTempFileName();
            ControlMessages msg = ControlMessages.getInstance();
            XmlDocument doc = new XmlDocument();
            doc.PreserveWhitespace = true;
            string infoSchema = String.Empty;
            if (formatoFactura.Equals(InvoceTypes.FACTURAE_3_1))
            {
                infoSchema = msg.getMessage(ControlMessages.Msg.MsgInfoSchemaFacturae31);
            }
            else
            {
                infoSchema = msg.getMessage(ControlMessages.Msg.MsgInfoSchemaFacturae32);
            }
            string infoAccount = msg.getMessage(ControlMessages.Msg.MsgAccountOK);
            string infoSigned = msg.getMessage(ControlMessages.Msg.MsgSignedOK);
            string infoSignedType = msg.getMessage(ControlMessages.Msg.MsgInfoSignedType);
            string infoIssue = msg.getMessage(ControlMessages.Msg.MsgInfoIssued);
            string infoSubject = msg.getMessage(ControlMessages.Msg.MsgInfoSubject);
            string infoCertificateStatus = msg.getMessage(ControlMessages.Msg.MsgInfoCertificateStatus);
            string desconocido = msg.getMessage(ControlMessages.Msg.MsgUnknown);
            string OCSP = string.Empty;
            string statusOCSP = string.Empty;
            FrmValidation f = new FrmValidation();
            try
            {
                exportPaperInvoice(temporalExportPath, formatoFactura, false);
                doc.Load(temporalExportPath);
            }

            catch (Exception ex)
            {
                if (agregarRecibidas)
                {
                    if (MessageBox.Show(msg.getMessage(ControlMessages.Msg.ErrorAddToReceived), msg.getMessage(ControlMessages.Msg.CaptionFacturae), MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.No)
                    {
                        return false;
                    }
                }
                f.setImages(false, false, false, msg.getMessage(ControlMessages.Msg.MsgSchemaV31MalFormat), ex.Message, msg.getMessage(ControlMessages.Msg.MsgNoAccountValidation), "", msg.getMessage(ControlMessages.Msg.MsfNoSignedValidation), "", infoSignedType + desconocido, infoIssue + desconocido, infoSubject + desconocido, infoCertificateStatus + desconocido, null, null, desconocido, desconocido, false, false);
                f.ShowDialog();
                return false;
            }

            try
            {
                if (formatoFactura.Equals(InvoceTypes.FACTURAE_3_1))
                {
                    InvoiceValidations.ValidationAccountingV31(doc);
                }
                else
                {
                    InvoiceValidations.ValidationAccountingV32(doc);
                }
                if (!agregarRecibidas)
                {
                    f.setImages(true, true, false, infoSchema, "", infoAccount, "", msg.getMessage(ControlMessages.Msg.MsgErrorSignedValidation), msg.getMessage(ControlMessages.Msg.ErrorInvoiceNotSignated), infoSignedType, infoIssue, infoSubject, infoCertificateStatus + desconocido, doc, null, OCSP, statusOCSP, false, false);
                    f.ShowDialog();
                }
                return true;
            }
            catch (Exception ex)
            {
                if (agregarRecibidas)
                {
                    if (MessageBox.Show(msg.getMessage(ControlMessages.Msg.ErrorAddToReceived), msg.getMessage(ControlMessages.Msg.CaptionRibbon), MessageBoxButtons.YesNo, MessageBoxIcon.Stop) == DialogResult.No)
                    {
                        return false;
                    }
                }
                f.setImages(true, false, false, infoSchema, "", msg.getMessage(ControlMessages.Msg.MsgErrorAccountValidation), ex.Message, msg.getMessage(ControlMessages.Msg.MsfNoSignedValidation), "", infoSignedType + desconocido, infoIssue + desconocido, infoSubject + desconocido, infoCertificateStatus + desconocido, null, null, desconocido, desconocido, false, false);
                f.ShowDialog();
                return false;
            }
        }

        /// <summary>
        /// Método que valida una factura en formato Facturae
        /// </summary>
        /// <param name="doc">XML con la factura</param>
        /// <param name="agregarRecibidas">Parámetro que indica si la factura se desea agregar a recibidas o no</param>
        /// <returns>Resultado de la validación</returns>
        public bool validateFacturae(XmlDocument doc, bool agregarRecibidas)
        {
            ControlMessages msg = ControlMessages.getInstance();

            string infoSchema = String.Empty;
            string infoAccount = msg.getMessage(ControlMessages.Msg.MsgAccountOK);
            string infoSigned = msg.getMessage(ControlMessages.Msg.MsgSignedOK);
            string infoSignedType = msg.getMessage(ControlMessages.Msg.MsgInfoSignedType);
            string infoIssue = msg.getMessage(ControlMessages.Msg.MsgInfoIssued);
            string infoSubject = msg.getMessage(ControlMessages.Msg.MsgInfoSubject);
            string infoCertificateStatus = msg.getMessage(ControlMessages.Msg.MsgInfoCertificateStatus);
            string desconocido = msg.getMessage(ControlMessages.Msg.MsgUnknown);
            string OCSP = string.Empty;
            string statusOCSP = string.Empty;
            bool isEpes = false;

            bool schema = true;
            bool account = true;

            string errorSchema = string.Empty;
            string errorAccount = string.Empty;
            string errorSigned = string.Empty;

            if (doc.DocumentElement.NamespaceURI.Equals("http://www.facturae.es/Facturae/2007/v3.1/Facturae"))
            {
                infoSchema = msg.getMessage(ControlMessages.Msg.MsgInfoSchemaFacturae31);
            }
            else if (doc.DocumentElement.NamespaceURI.Equals("http://www.facturae.es/Facturae/2009/v3.2/Facturae"))
            {
                infoSchema = msg.getMessage(ControlMessages.Msg.MsgInfoSchemaFacturae32);
            }

            FrmValidation f = new FrmValidation();

            XmlDocument docFirmado = new XmlDocument();
            docFirmado.PreserveWhitespace = true;
            docFirmado.LoadXml(doc.OuterXml);

            XmlNode signatureNode = doc.DocumentElement.GetElementsByTagName("Signature").Item(0);
            if (signatureNode == null)
                signatureNode = doc.DocumentElement.GetElementsByTagName("ds:Signature").Item(0);
            if (signatureNode != null)
            {
                doc.DocumentElement.RemoveChild(signatureNode);
            }

            doc.Save(System.Environment.GetEnvironmentVariable("APPDATA") + Paths.InvoiceExtractPath);

            try
            {
                if (System.IO.File.Exists(System.Environment.GetEnvironmentVariable("APPDATA") + Paths.InvoiceExtractPath))
                {
                    XmlRootAttribute rootAttribute = new XmlRootAttribute();
                    rootAttribute.Namespace = doc.DocumentElement.NamespaceURI;
                    rootAttribute.IsNullable = false;

                    XmlSerializer serializer = new XmlSerializer(typeof(Facturae), rootAttribute);
                    System.IO.StreamReader r = new System.IO.StreamReader(System.Environment.GetEnvironmentVariable("APPDATA") + Paths.InvoiceExtractPath);
                    Facturae copia = (Facturae)serializer.Deserialize(r);
                    r.Close();
                }
            }
            catch (Exception ex)
            {
                if (agregarRecibidas)
                {
                    if (MessageBox.Show(msg.getMessage(ControlMessages.Msg.ErrorAddToReceived), msg.getMessage(ControlMessages.Msg.CaptionFacturae), MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.No)
                    {
                        return false;
                    }
                }
                schema = false;
                infoSchema = msg.getMessage(ControlMessages.Msg.MsgSchemaV31MalFormat);
                errorSchema = ex.Message;
            }

            try
            {
                if (doc.DocumentElement.NamespaceURI.Equals("http://www.facturae.es/Facturae/2007/v3.1/Facturae"))
                {
                    InvoiceValidations.ValidationAccountingV31(doc);
                }
                else if (doc.DocumentElement.NamespaceURI.Equals("http://www.facturae.es/Facturae/2009/v3.2/Facturae"))
                {
                    InvoiceValidations.ValidationAccountingV32(doc);
                }


            }
            catch (Exception ex)
            {
                if (agregarRecibidas)
                {
                    if (MessageBox.Show(msg.getMessage(ControlMessages.Msg.ErrorAddToReceived), msg.getMessage(ControlMessages.Msg.CaptionFacturae), MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.No)
                    {
                        return false;
                    }
                }
                account = false;
                infoAccount = msg.getMessage(ControlMessages.Msg.MsgErrorAccountValidation);
                errorAccount = ex.Message;
            }
            XadesSignature xadesSignature = new XadesSignature();
            try
            {

                xadesSignature.XadesValidation(docFirmado, false);
                try
                {
                    string tipoFimra = "";
                    tipoFimra = xadesSignature.ObtenerTipoFirma(docFirmado);
                    if (tipoFimra.Equals("XADES-EPES"))
                        isEpes = true;
                    else if (tipoFimra.Equals("XADES-XL"))
                    {
                        isEpes = false;
                    }
                    infoSignedType += tipoFimra;
                }
                catch (Exception)
                {
                    infoSignedType += desconocido;
                }
                try
                {
                    infoIssue += xadesSignature.ObtenerDatosEmisor(docFirmado);
                }
                catch (Exception)
                {
                    infoIssue += desconocido;
                }
                try
                {
                    infoSubject += xadesSignature.ObtenerDatosFirmante(docFirmado);
                }
                catch (Exception)
                {
                    infoSubject += desconocido;
                }
                try
                {
                    OCSP = xadesSignature.obtenerOCSP(docFirmado);
                }
                catch (Exception)
                {
                    OCSP += desconocido;
                }
                try
                {
                    statusOCSP = xadesSignature.obtenerEstadoOCSP(docFirmado, OCSP);
                }
                catch (Exception)
                {
                    statusOCSP += desconocido;
                }
            }
            catch (Exception e)
            {
                if (agregarRecibidas)
                {
                    if (MessageBox.Show(msg.getMessage(ControlMessages.Msg.ErrorAddToReceived), msg.getMessage(ControlMessages.Msg.CaptionRibbon), MessageBoxButtons.YesNo, MessageBoxIcon.Stop) == DialogResult.No)
                    {
                        return false;
                    }
                }
                try
                {
                    string tipoFimra = "";
                    tipoFimra = xadesSignature.ObtenerTipoFirma(docFirmado);
                    if (tipoFimra.Equals("XADES-EPES"))
                        isEpes = true;
                    else if (tipoFimra.Equals("XADES-XL"))
                    {
                        isEpes = false;
                    }
                    infoSignedType += tipoFimra;
                }
                catch (Exception)
                {
                    infoSignedType += desconocido;
                }
                try
                {
                    infoIssue += xadesSignature.ObtenerDatosEmisor(docFirmado);
                }
                catch (Exception)
                {
                    infoIssue += desconocido;
                }
                try
                {
                    infoSubject += xadesSignature.ObtenerDatosFirmante(docFirmado);
                }
                catch (Exception)
                {
                    infoSubject += desconocido;
                }
                try
                {
                    OCSP = xadesSignature.obtenerOCSP(docFirmado);
                }
                catch (Exception)
                {
                    OCSP += desconocido;
                }
                try
                {
                    statusOCSP = xadesSignature.obtenerEstadoOCSP(docFirmado, OCSP);
                }
                catch (Exception)
                {
                    statusOCSP += desconocido;
                }
                f.setImages(schema, account, false, infoSchema, errorSchema, infoAccount, errorAccount, msg.getMessage(ControlMessages.Msg.MsgErrorSignedValidation), msg.getMessage(e.Message), infoSignedType, infoIssue, infoSubject, infoCertificateStatus + desconocido, docFirmado, xadesSignature.obtenerTimeStampToken(docFirmado), OCSP, statusOCSP, true, isEpes);
                f.ShowDialog();
                return false;
            }
            if (!agregarRecibidas)
            {
                f.setImages(schema, account, true, infoSchema, errorSchema, infoAccount, errorAccount, infoSigned, "", infoSignedType, infoIssue, infoSubject, infoCertificateStatus, docFirmado, xadesSignature.obtenerTimeStampToken(docFirmado), OCSP, statusOCSP, true, isEpes);
                f.ShowDialog();
            }
            return true;
        }

        /// <summary>
        /// Método que realiza la validación de una factura en formato UBL
        /// </summary>
        /// <param name="doc">XML con la factura</param>
        /// <param name="agregarRecibidas">Parámetro que indica si la factura se desea agregar a recibidas o no</param>
        /// <returns>Resultados de la validación</returns>
        public bool validateUBL(XmlDocument doc, bool agregarRecibidas)
        {
            XmlDocument docSinFirma = new XmlDocument();
            docSinFirma.PreserveWhitespace = true;
            docSinFirma.LoadXml(doc.OuterXml);

            XmlNode signatureNode = docSinFirma.DocumentElement.GetElementsByTagName("Signature").Item(0);
            if (signatureNode != null)
            {
                docSinFirma.DocumentElement.GetElementsByTagName("Signature", "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2").Item(0).RemoveChild(signatureNode);
            }

            ResultUBLValidation schema = UBLValidation.SchemaValidation(docSinFirma);
            ResultUBLValidation account = UBLValidation.AccountValidation(doc);
            ResultUBLValidation signed = UBLValidation.SignedValidation(doc);
            ControlMessages msg = ControlMessages.getInstance();
            string infoSchema = msg.getMessage(ControlMessages.Msg.MsgInfoSchemaUBL);
            string infoAccount = msg.getMessage(ControlMessages.Msg.MsgAccountOK);
            string infoSigned = msg.getMessage(ControlMessages.Msg.MsgSignedOK);
            string infoSignedType = msg.getMessage(ControlMessages.Msg.MsgInfoSignedType);
            string infoIssue = msg.getMessage(ControlMessages.Msg.MsgInfoIssued);
            string infoSubject = msg.getMessage(ControlMessages.Msg.MsgInfoSubject);
            string infoCertificateStatus = msg.getMessage(ControlMessages.Msg.MsgInfoCertificateStatus);
            string desconocido = msg.getMessage(ControlMessages.Msg.MsgUnknown);
            string OCSP = string.Empty;
            string statusOCSP = string.Empty;
            bool isEpes = false;
            FrmValidation f = new FrmValidation();

            if (!schema.Success)
            {
                if (agregarRecibidas)
                {
                    if (MessageBox.Show(msg.getMessage(ControlMessages.Msg.ErrorAddToReceived), msg.getMessage(ControlMessages.Msg.CaptionFacturae), MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.No)
                    {
                        return false;
                    }
                }
            }

            if (!account.Success)
            {
                if (agregarRecibidas)
                {
                    if (MessageBox.Show(msg.getMessage(ControlMessages.Msg.ErrorAddToReceived), msg.getMessage(ControlMessages.Msg.CaptionFacturae), MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.No)
                    {
                        return false;
                    }
                }
            }
            //XmlDocument docFirmado = new XmlDocument();
            //docFirmado.PreserveWhitespace = true;
            //docFirmado.LoadXml(doc.OuterXml);
            XadesSignature xadesSignature = new XadesSignature();
            if (signed.Success)
            {
                try
                {
                    string tipoFimra = "";
                    tipoFimra = xadesSignature.ObtenerTipoFirma(doc);
                    if (tipoFimra.Equals("XADES-EPES"))
                        isEpes = true;
                    else if (tipoFimra.Equals("XADES-XL"))
                    {
                        isEpes = false;
                    }
                    infoSignedType += tipoFimra;
                }
                catch (Exception)
                {
                    infoSignedType += desconocido;
                }
                try
                {
                    infoIssue += xadesSignature.ObtenerDatosEmisor(doc);
                }
                catch (Exception)
                {
                    infoIssue += desconocido;
                }
                try
                {
                    infoSubject += xadesSignature.ObtenerDatosFirmante(doc);
                }
                catch (Exception)
                {
                    infoSubject += desconocido;
                }
                try
                {
                    OCSP = xadesSignature.obtenerOCSP(doc);
                }
                catch (Exception)
                {
                    OCSP += desconocido;
                }
                try
                {
                    statusOCSP = xadesSignature.obtenerEstadoOCSP(doc, OCSP);
                }
                catch (Exception)
                {
                    statusOCSP += desconocido;
                }
            }
            else
            {
                if (agregarRecibidas)
                {
                    if (MessageBox.Show(msg.getMessage(ControlMessages.Msg.ErrorAddToReceived), msg.getMessage(ControlMessages.Msg.CaptionRibbon), MessageBoxButtons.YesNo, MessageBoxIcon.Stop) == DialogResult.No)
                    {
                        return false;
                    }
                }
                try
                {
                    string tipoFimra = "";
                    tipoFimra = xadesSignature.ObtenerTipoFirma(doc);
                    if (tipoFimra.Equals("XADES-EPES"))
                        isEpes = true;
                    else if (tipoFimra.Equals("XADES-XL"))
                    {
                        isEpes = false;
                    }
                    infoSignedType += tipoFimra;
                }
                catch (Exception)
                {
                    infoSignedType += desconocido;
                }
                try
                {
                    infoIssue += xadesSignature.ObtenerDatosEmisor(doc);
                }
                catch (Exception)
                {
                    infoIssue += desconocido;
                }
                try
                {
                    infoSubject += xadesSignature.ObtenerDatosFirmante(doc);
                }
                catch (Exception)
                {
                    infoSubject += desconocido;
                }
                try
                {
                    OCSP = xadesSignature.obtenerOCSP(doc);
                }
                catch (Exception)
                {
                    OCSP += desconocido;
                }
                try
                {
                    statusOCSP = xadesSignature.obtenerEstadoOCSP(doc, OCSP);
                }
                catch (Exception)
                {
                    statusOCSP += desconocido;
                }
                f.setImages(schema.Success, account.Success, signed.Success, infoSchema, schema.MsgError, infoAccount, account.MsgError, msg.getMessage(ControlMessages.Msg.MsgErrorSignedValidation), msg.getMessage(signed.MsgError), infoSignedType, infoIssue, infoSubject, infoCertificateStatus + desconocido, doc, xadesSignature.obtenerTimeStampToken(doc), OCSP, statusOCSP, true, isEpes);
                f.ShowDialog();
                return false;
            }
            if (!agregarRecibidas)
            {
                f.setImages(schema.Success, account.Success, signed.Success, infoSchema, schema.MsgError, infoAccount, account.MsgError, infoSigned, "", infoSignedType, infoIssue, infoSubject, infoCertificateStatus, doc, xadesSignature.obtenerTimeStampToken(doc), OCSP, statusOCSP, true, isEpes);
                f.ShowDialog();
            }
            return true;
        }



        /// <summary>
        /// Método que realiza la validación de una factura en formato CII
        /// </summary>
        /// <param name="doc">XML con la factura</param>
        /// <param name="agregarRecibidas">Parámetro que indica si la factura se desea agregar a recibidas o no</param>
        /// <returns>Resultados de la validación</returns>
        public bool validateCII(XmlDocument doc, bool agregarRecibidas)
        {
            XmlDocument docSinFirma = new XmlDocument();
            docSinFirma.PreserveWhitespace = true;
            docSinFirma.LoadXml(doc.OuterXml);

            XmlNode signatureNode = docSinFirma.DocumentElement.GetElementsByTagName("Signature").Item(0);
            if (signatureNode == null)
                signatureNode = docSinFirma.DocumentElement.GetElementsByTagName("ds:Signature").Item(0);
            if (signatureNode != null)
            {
                docSinFirma.DocumentElement.RemoveChild(signatureNode);
            }

            ResultCIIValidation schema = CIIValidation.SchemaValidation(docSinFirma);
            ResultCIIValidation account = CIIValidation.AccountValidation(doc);
            ResultCIIValidation signed = CIIValidation.SignedValidation(doc);
            ControlMessages msg = ControlMessages.getInstance();
            string infoSchema = msg.getMessage(ControlMessages.Msg.MsgInfoSchemaCII);
            string infoAccount = msg.getMessage(ControlMessages.Msg.MsgAccountOK);
            string infoSigned = msg.getMessage(ControlMessages.Msg.MsgSignedOK);
            string infoSignedType = msg.getMessage(ControlMessages.Msg.MsgInfoSignedType);
            string infoIssue = msg.getMessage(ControlMessages.Msg.MsgInfoIssued);
            string infoSubject = msg.getMessage(ControlMessages.Msg.MsgInfoSubject);
            string infoCertificateStatus = msg.getMessage(ControlMessages.Msg.MsgInfoCertificateStatus);
            string desconocido = msg.getMessage(ControlMessages.Msg.MsgUnknown);
            string OCSP = string.Empty;
            string statusOCSP = string.Empty;
            bool isEpes = false;
            FrmValidation f = new FrmValidation();

            if (!schema.Success)
            {
                if (agregarRecibidas)
                {
                    if (MessageBox.Show(msg.getMessage(ControlMessages.Msg.ErrorAddToReceived), msg.getMessage(ControlMessages.Msg.CaptionFacturae), MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.No)
                    {
                        return false;
                    }
                }
            }

            if (!account.Success)
            {
                if (agregarRecibidas)
                {
                    if (MessageBox.Show(msg.getMessage(ControlMessages.Msg.ErrorAddToReceived), msg.getMessage(ControlMessages.Msg.CaptionFacturae), MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.No)
                    {
                        return false;
                    }
                }
            }
            //XmlDocument docFirmado = new XmlDocument();
            //docFirmado.PreserveWhitespace = true;
            //docFirmado.LoadXml(doc.OuterXml);
            XadesSignature xadesSignature = new XadesSignature();
            if (signed.Success)
            {
                try
                {
                    string tipoFimra = "";
                    tipoFimra = xadesSignature.ObtenerTipoFirma(doc);
                    if (tipoFimra.Equals("XADES-EPES"))
                        isEpes = true;
                    else if (tipoFimra.Equals("XADES-XL"))
                    {
                        isEpes = false;
                    }
                    infoSignedType += tipoFimra;
                }
                catch (Exception)
                {
                    infoSignedType += desconocido;
                }
                try
                {
                    infoIssue += xadesSignature.ObtenerDatosEmisor(doc);
                }
                catch (Exception)
                {
                    infoIssue += desconocido;
                }
                try
                {
                    infoSubject += xadesSignature.ObtenerDatosFirmante(doc);
                }
                catch (Exception)
                {
                    infoSubject += desconocido;
                }
                try
                {
                    OCSP = xadesSignature.obtenerOCSP(doc);
                }
                catch (Exception)
                {
                    OCSP += desconocido;
                }
                try
                {
                    statusOCSP = xadesSignature.obtenerEstadoOCSP(doc, OCSP);
                }
                catch (Exception)
                {
                    statusOCSP += desconocido;
                }
            }
            else
            {
                if (agregarRecibidas)
                {
                    if (MessageBox.Show(msg.getMessage(ControlMessages.Msg.ErrorAddToReceived), msg.getMessage(ControlMessages.Msg.CaptionRibbon), MessageBoxButtons.YesNo, MessageBoxIcon.Stop) == DialogResult.No)
                    {
                        return false;
                    }
                }
                try
                {
                    string tipoFimra = "";
                    tipoFimra = xadesSignature.ObtenerTipoFirma(doc);
                    if (tipoFimra.Equals("XADES-EPES"))
                        isEpes = true;
                    else if (tipoFimra.Equals("XADES-XL"))
                    {
                        isEpes = false;
                    }
                    infoSignedType += tipoFimra;
                }
                catch (Exception)
                {
                    infoSignedType += desconocido;
                }
                try
                {
                    infoIssue += xadesSignature.ObtenerDatosEmisor(doc);
                }
                catch (Exception)
                {
                    infoIssue += desconocido;
                }
                try
                {
                    infoSubject += xadesSignature.ObtenerDatosFirmante(doc);
                }
                catch (Exception)
                {
                    infoSubject += desconocido;
                }
                try
                {
                    OCSP = xadesSignature.obtenerOCSP(doc);
                }
                catch (Exception)
                {
                    OCSP += desconocido;
                }
                try
                {
                    statusOCSP = xadesSignature.obtenerEstadoOCSP(doc, OCSP);
                }
                catch (Exception)
                {
                    statusOCSP += desconocido;
                }
                f.setImages(schema.Success, account.Success, signed.Success, infoSchema, schema.MsgError, infoAccount, account.MsgError, msg.getMessage(ControlMessages.Msg.MsgErrorSignedValidation), msg.getMessage(signed.MsgError), infoSignedType, infoIssue, infoSubject, infoCertificateStatus + desconocido, doc, xadesSignature.obtenerTimeStampToken(doc), OCSP, statusOCSP, true, isEpes);
                f.ShowDialog();
                return false;
            }
            if (!agregarRecibidas)
            {
                f.setImages(schema.Success, account.Success, signed.Success, infoSchema, schema.MsgError, infoAccount, account.MsgError, infoSigned, "", infoSignedType, infoIssue, infoSubject, infoCertificateStatus, doc, xadesSignature.obtenerTimeStampToken(doc), OCSP, statusOCSP, true, isEpes);
                f.ShowDialog();
            }
            return true;
        }




        /// <summary>
        /// Método que exporta una factura en papel
        /// </summary>
        /// <param name="path">Path de la factura</param>
        /// <param name="formatoFactura">Formato de la factura</param>
        /// <param name="notify">Notificación</param>
        /// <returns></returns>
        private Facturae exportPaperInvoice(string path, int formatoFactura, bool notify)
        {
            try
            {
                FacturaeFieldAndValues datos = new FacturaeFieldAndValues();
                foreach (Microsoft.Office.Interop.Word.ContentControl item in Globals.ThisAddIn.Application.ActiveDocument.ContentControls)
                {
                    if (!string.IsNullOrEmpty(item.Tag) && !string.IsNullOrEmpty(item.Range.Text))
                    {
                        string value = item.Range.Text.Trim();
                        if (item.Tag.Equals("TH_PersonTypeCode")
                            || item.Tag.Equals("TH_ResidenceTypeCode")
                            || item.Tag.Equals("TH_CountryCode")
                            || item.Tag.Equals("SP_PersonTypeCode")
                            || item.Tag.Equals("SP_ResidenceTypeCode")
                            || item.Tag.Equals("SP_CountryCode")
                            || item.Tag.Equals("BP_PersonTypeCode")
                            || item.Tag.Equals("BP_ResidenceTypeCode")
                            || item.Tag.Equals("BP_CountryCode")
                            || item.Tag.Equals("IH_InvoiceDocumentType")
                            || item.Tag.Equals("IH_InvoiceClass")
                            //|| item.Tag.Equals("CORR_ReasonCode")
                            || item.Tag.Equals("CORR_ReasonDescription")
                            //|| item.Tag.Equals("CORR_CorrectionMethod")
                            || item.Tag.Equals("CORR_CorrectionMethodDescription")
                            || item.Tag.Equals("InvoiceIssuerType"))
                        {
                            /*si lo encontramos buscamos el valor correspondiente al texto seleccionado*/
                            foreach (ContentControlListEntry entry in item.DropdownListEntries)
                            {
                                if (!string.IsNullOrEmpty(item.Tag))
                                {
                                    if (entry.Text.ToLower().Equals(value.ToLower()))
                                    {
                                        if (item.Tag.Equals("CORR_ReasonDescription"))
                                        {
                                            datos.setFieldAndValue("CORR_ReasonDescription_Value", entry.Value);
                                            break;
                                        }
                                        else if (item.Tag.Equals("CORR_CorrectionMethodDescription"))
                                        {
                                            datos.setFieldAndValue("CORR_CorrectionMethodDescription_Value", entry.Value);
                                            break;
                                        }
                                        else
                                        {
                                            value = entry.Value; break;
                                        }
                                    }
                                }

                            }
                        }
                        datos.setFieldAndValue(item.Tag, value);
                    }
                }

                FacturaeGenerator generador = new FacturaeGenerator(new Facturae(), Globals.ThisAddIn.Application.ActiveDocument, true, formatoFactura, calculos, datos);
                Facturae paperInvoice = generador.getFacturae();

                XmlRootAttribute rootAttribute = new XmlRootAttribute();
                if (formatoFactura.Equals(InvoceTypes.FACTURAE_3_1))
                {
                    rootAttribute.Namespace = "http://www.facturae.es/Facturae/2007/v3.1/Facturae";
                }
                else
                {
                    rootAttribute.Namespace = "http://www.facturae.es/Facturae/2009/v3.2/Facturae";
                }
                rootAttribute.IsNullable = false;

                XmlSerializer serializer = new XmlSerializer(typeof(Facturae), rootAttribute);
                System.IO.StreamWriter w = new System.IO.StreamWriter(path);

                XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                ns.Add("namespace", "http://www.facturae.es/Facturae/2007/v3.0/Facturae");
                if (formatoFactura.Equals(InvoceTypes.FACTURAE_3_1))
                {
                    ns.Add("", "http://www.facturae.es/Facturae/2007/v3.1/Facturae");
                }
                else
                {
                    ns.Add("", "http://www.facturae.es/Facturae/2009/v3.2/Facturae");
                }
                ns.Add("namespace2", "http://uri.etsi.org/01903/v1.3.2#");
                ns.Add("namespace3", "http://www.w3.org/2000/09/xmldsig#");

                serializer.Serialize(w, paperInvoice, ns);
                w.Close();

                if (notify)
                {
                    ControlMessages controlM = ControlMessages.getInstance();
                    MessageBox.Show(controlM.getMessage(ControlMessages.Msg.InfoExportedInvoice), controlM.getMessage(ControlMessages.Msg.CaptionFacturae), MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
                }
                return paperInvoice;
            }
            catch (Exception)
            {
                return null;
            }
        }


        /// <summary>
        /// Método que realiza una validacion contable de un archivo cuyo path lo
        /// recibe por parámetro.
        /// </summary>
        /// <param name="path">Parámetro de tipo string con el path del archivo a validar</param>
        /// <param name="import">Parámetro de tipo bool que indica si es una importación o no</param>
        /// <param name="formatoFactura">Formato de la factura</param>
        public void AccountingValidation(string path, bool import, int formatoFactura)
        {
            XmlDocument doc = new XmlDocument();
            doc.PreserveWhitespace = false;
            doc.Load(path);
            try
            {
                if (formatoFactura.Equals(InvoceTypes.FACTURAE_3_1))
                {
                    InvoiceValidations.ValidationAccountingV31(doc);
                }
                else if (formatoFactura.Equals(InvoceTypes.FACTURAE_3_2))
                {
                    InvoiceValidations.ValidationAccountingV32(doc);
                }
                else if (formatoFactura.Equals(InvoceTypes.UBL))
                {
                    InvoiceValidations.ValidationAccountingUBL(path);
                }
                else if (formatoFactura.Equals(InvoceTypes.CII))
                {
                    InvoiceValidations.ValidationAccountingCII(path);
                }
            }
            catch (Exception e)
            {
                if (import)
                {
                    throw e;
                }
                ControlMessages controlM = ControlMessages.getInstance();
                throw new Exception(controlM.getMessage(e.Message));
            }

        }

        /// <summary>
        /// Método que realiza una validacion de firma de un archivo cuyo path lo
        /// recibe por parámetro.
        /// </summary>
        /// <param name="path">Parámetro de tipo string con el path del archivo a validar</param>
        public void SignatureValidations(string path)
        {

            try
            {
                XmlDocument signedDoc = new XmlDocument();
                signedDoc.PreserveWhitespace = true;
                signedDoc.Load(path);

                XadesSignature xadesSignature = new XadesSignature();
                xadesSignature.XadesValidation(signedDoc, false);

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        #endregion
    }
}
